import axios, {
  AxiosResponse,
  AxiosInstance,
  AxiosRequestConfig,
  AxiosError,
} from "axios";

/**
 * 响应数据包装类
 */
export class ResData {
  httpStatus: number | undefined;
  success = false;
  info = "";
  data: any;
  code: string | undefined;
  error: any;
  originData: any;

  constructor(options: any) {
    const { status, data, info, originData, error } = options;
    this.httpStatus = status;
    this.data = data;
    this.info = info;
    this.originData = originData;
    this.error = error;
  }
}

const SUCCESS_CODE = "000000";
const DEFAULT_CONFIG = {
  timeout: 60 * 1000,
  headers: {
    // post: {
    //   "Content-Type": "application/x-www-form-urlencoded",
    // },
  },
  // validateStatus: () => true,
};

let instance: AxiosInstance;

instance = axios.create(DEFAULT_CONFIG);

function defalutConvertResData(res: AxiosResponse) {
  const { data: originData, status } = res;
  const resData = new ResData({
    status,
    originData,
  });
  if (originData) {
    const { data, code, info } = originData;
    resData.code = code;
    resData.data = data;
    resData.info = info;
    resData.success = code === SUCCESS_CODE;
  }
  return resData;
}

function config(config: AxiosRequestConfig) {
  instance.interceptors.request.use((config) => {
    return config;
  });
  instance.interceptors.response.use(
    (res) => {
      const resData = defalutConvertResData(res);
      return resData;
    },
    (error) => {
      // console.log(error.request);
      // console.log(error.response);
      const info = getHttpErrorMessage(error);
      const resData = new ResData({
        error,
        info,
      });
      resData.success = false;
      return resData;
    }
  );
}

/**
 * 处理异常
 * @param {*} error
 */
function getHttpErrorMessage(error: AxiosError) {
  let message = "";
  // 处理被取消的请求
  if (axios.isCancel(error)) {
    console.error("请求的重复请求：" + error.message);
    return;
  }
  if (error && error.response) {
    switch (error.response.status) {
      case 302:
        message = "接口重定向了";
        break;
      case 400:
        message = "参数不正确";
        break;
      case 401:
        message = "您未登录，或者登录已经超时，请先登录";
        break;
      case 403:
        message = "您没有权限操作";
        break;
      case 404:
        message = `请求地址出错`;
        break; // 在正确域名下
      case 408:
        message = "请求超时";
        break;
      case 409:
        message = "系统已存在相同数据";
        break;
      case 500:
        message = "服务器内部错误";
        break;
      case 501:
        message = "服务未实现";
        break;
      case 502:
        message = "网关错误";
        break;
      case 503:
        message = "服务不可用";
        break;
      case 504:
        message = "服务暂时无法访问，请稍后再试";
        break;
      case 505:
        message = "HTTP版本不受支持";
        break;
      default:
        message = "异常问题，请联系管理员";
        break;
    }
  }
  if (error.message.includes("timeout")) {
    message = "网络请求超时";
  }
  if (error.message.includes("Network")) {
    message = window.navigator.onLine ? "网络异常" : "您断网了";
  }
  return message;
}

export function request(config: AxiosRequestConfig): Promise<ResData> {
  return new Promise((resolve) => {
    instance.request(config).then((res: any) => resolve(res));
  });
}

export function get(
  url: string,
  config?: AxiosRequestConfig
): Promise<ResData> {
  return new Promise((resolve) => {
    instance.get(url, config).then((res: any) => resolve(res));
  });
}

export function post(
  url: string,
  data?: any,
  config?: AxiosRequestConfig
): Promise<ResData> {
  return new Promise((resolve) => {
    instance.get(url, config).then((res: any) => resolve(res));
  });
}

export { axios };

config({});
